package com.lan.parse;

import com.lan.ScriptContext;
import com.lan.antlr.ScriptBaseListener;
import com.lan.antlr.ScriptParser;
import com.lan.model.symbol.*;
import org.antlr.v4.runtime.ParserRuleContext;
import org.apache.commons.lang3.StringUtils;


public class Resolver extends ScriptBaseListener {

    private ScriptContext context;

    private StackSymbol stackSymbol;

    public Resolver(ScriptContext context) {
        this.context = context;
        stackSymbol = new StackSymbol();
    }

    private void print(ParserRuleContext ctx, String name) {
        System.out.println(ctx.getRuleIndex() + " :   " + ctx.toString() + "   " + (StringUtils.isNotBlank(name) ? name : "") + " " + (StringUtils.isNotBlank(ctx.getText()) ? ctx.getText() : ""));
    }

    @Override
    public void enterProg(ScriptParser.ProgContext ctx) {
        Block root = new Block("root", null, "root", ctx);
        SymbolTree symbolTree = new SymbolTree(root);
        context.setSymbolTree(symbolTree);
        stackSymbol.pushScope(symbolTree);
    }

    @Override
    public void enterFunctionDeclaration(ScriptParser.FunctionDeclarationContext ctx) {
        if (ctx.FUNCTION() != null && ctx.name() != null) {
            String name = ctx.name().getText();
            Scope scope = stackSymbol.get().getScope();
            String id = stackSymbol.getNowId();
            Function function = new Function(name, scope, id, ctx);
            SymbolTree symbolTree = new SymbolTree(function);
            stackSymbol.pushScope(symbolTree);
        }

    }

    @Override
    public void exitFunctionDeclaration(ScriptParser.FunctionDeclarationContext ctx) {
        stackSymbol.pop();
    }

    @Override
    public void enterClassDeclaration(ScriptParser.ClassDeclarationContext ctx) {
        String name = ctx.name().getText();
        String id = stackSymbol.getNowId();
        Clazz theClazz = new Clazz(name, id, ctx);
        SymbolTree symbolTree = new SymbolTree(theClazz);
        stackSymbol.pushScope(symbolTree);
    }

    @Override
    public void exitClassDeclaration(ScriptParser.ClassDeclarationContext ctx) {
        stackSymbol.pop();
    }


    @Override
    public void enterStatement(ScriptParser.StatementContext ctx) {
        if (ctx.FOR() != null) {
            String id = stackSymbol.getNowId();
            Block block = new Block("FOR", stackSymbol.getScope(), id + "_FOR", ctx);
            SymbolTree symbolTree = new SymbolTree(block);
            stackSymbol.pushScope(symbolTree);
        }
    }

    @Override
    public void exitStatement(ScriptParser.StatementContext ctx) {
        if (ctx.FOR() != null) {
            stackSymbol.pop();
        }
    }


    @Override
    public void enterBlock(ScriptParser.BlockContext ctx) {
        if (!(ctx.parent instanceof ScriptParser.FunctionBodyContext)) {
            String id = stackSymbol.getNowId();
            Block block = new Block("Block", stackSymbol.getScope(), id + "_Block", ctx);
            SymbolTree symbolTree = new SymbolTree(block);
            stackSymbol.pushScope(symbolTree);
        }
    }

    @Override
    public void exitBlock(ScriptParser.BlockContext ctx) {
        if (!(ctx.parent instanceof ScriptParser.FunctionBodyContext)) {
            stackSymbol.pop();
        }
    }


//    @Override
//    public void enterVariableDeclaratorId(ScriptParser.VariableDeclaratorIdContext ctx) {
//        String name = ctx.name().getText();
//        String parentId = stackSymbol.getNowId();
//        String id = parentId + "_var_" + name;
//
//        Variable variable = stackSymbol.getVariable(name);
//        if (variable == null) {
//            variable = new Variable(name, stackSymbol.getScope(), id);
//            SymbolContext symbolContext = new SymbolContext(variable);
//            stackSymbol.push(symbolContext);
//        }
//    }
}




















